---
// fetch all commits for just this page's path
type Props = {
	path: string;
};
const { path } = Astro.props as Props;
const resolvedPath = `examples/docs/${path}`;
const url = `https://api.github.com/repos/withastro/astro/commits?path=${resolvedPath}`;
const commitsURL = `https://github.com/withastro/astro/commits/main/${resolvedPath}`;

type Commit = {
	author: {
		id: string;
		login: string;
	};
};

async function getCommits(url: string) {
	try {
		const token = import.meta.env.SNOWPACK_PUBLIC_GITHUB_TOKEN ?? 'hello';
		if (!token) {
			throw new Error(
				'Cannot find "SNOWPACK_PUBLIC_GITHUB_TOKEN" used for escaping rate-limiting.'
			);
		}

		const auth = `Basic ${Buffer.from(token, 'binary').toString('base64')}`;

		const res = await fetch(url, {
			method: 'GET',
			headers: {
				Authorization: auth,
				'User-Agent': 'astro-docs/1.0',
			},
		});

		const data = await res.json();

		if (!res.ok) {
			throw new Error(
				`Request to fetch commits failed. Reason: ${res.statusText}
       Message: ${data.message}`
			);
		}

		return data as Commit[];
	} catch (e) {
		console.warn(`[error]  /src/components/AvatarList.astro 
    ${(e as any)?.message ?? e}`);
		return [] as Commit[];
	}
}

function removeDups(arr: Commit[]) {
	const map = new Map<string, Commit['author']>();

	for (let item of arr) {
		const author = item.author;
		// Deduplicate based on author.id
		map.set(author.id, { login: author.login, id: author.id });
	}

	return [...map.values()];
}

const data = await getCommits(url);
const unique = removeDups(data);
const recentContributors = unique.slice(0, 3); // only show avatars for the 3 most recent contributors
const additionalContributors = unique.length - recentContributors.length; // list the rest of them as # of extra contributors
---

<!-- Thanks to @5t3ph for https://smolcss.dev/#smol-avatar-list! -->
<div class="contributors">
	<ul class="avatar-list" style={`--avatar-count: ${recentContributors.length}`}>
		{recentContributors.map((item) => (
			<li>
				<a href={`https://github.com/${item.login}`}>
					<img
						alt={`Contributor ${item.login}`}
						title={`Contributor ${item.login}`}
						width="64"
						height="64"
						src={`https://avatars.githubusercontent.com/u/${item.id}`}
					/>
				</a>
			</li>
		))}
	</ul>
	{additionalContributors > 0 && (
		<span>
			<a href={commitsURL}>{`and ${additionalContributors} additional contributor${
				additionalContributors > 1 ? 's' : ''
			}.`}</a>
		</span>
	)}
	{unique.length === 0 && <a href={commitsURL}>Contributors</a>}
</div>

<style>
	.avatar-list {
		--avatar-size: 2.5rem;
		--avatar-count: 3;

		display: grid;
		list-style: none;
		/* Default to displaying most of the avatar to
  enable easier access on touch devices, ensuring
  the WCAG touch target size is met or exceeded */
		grid-template-columns: repeat(var(--avatar-count), max(44px, calc(var(--avatar-size) / 1.15)));
		/* `padding` matches added visual dimensions of
  the `box-shadow` to help create a more accurate
  computed component size */
		padding: 0.08em;
		font-size: var(--avatar-size);
	}

	@media (any-hover: hover) and (any-pointer: fine) {
		.avatar-list {
			/* We create 1 extra cell to enable the computed 
    width to match the final visual width */
			grid-template-columns: repeat(calc(var(--avatar-count) + 1), calc(var(--avatar-size) / 1.75));
		}
	}

	.avatar-list li {
		width: var(--avatar-size);
		height: var(--avatar-size);
	}

	.avatar-list li:hover ~ li a,
	.avatar-list li:focus-within ~ li a {
		transform: translateX(33%);
	}

	.avatar-list img,
	.avatar-list a {
		display: block;
		border-radius: 50%;
	}

	.avatar-list a {
		transition: transform 180ms ease-in-out;
	}

	.avatar-list img {
		width: 100%;
		height: 100%;
		object-fit: cover;
		background-color: #fff;
		box-shadow: 0 0 0 0.05em #fff, 0 0 0 0.08em rgba(0, 0, 0, 0.15);
	}

	.avatar-list a:focus {
		outline: 2px solid transparent;
		/* Double-layer trick to work for dark and light backgrounds */
		box-shadow: 0 0 0 0.08em var(--theme-accent), 0 0 0 0.12em white;
	}

	.contributors {
		display: flex;
		align-items: center;
	}

	.contributors > * + * {
		margin-left: 0.75rem;
	}
</style>
